package br.ufrj.ppgi.greco.model.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.persistence.EntityManager;

public class DAOGeneric<T>
{

	private EntityManager em;
	private Class<T> entityClass;

	@SuppressWarnings("unchecked")
	public DAOGeneric(EntityManager em)
	{
		this.em = em;
		
		Type t = this.getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        this.entityClass = (Class<T>) pt.getActualTypeArguments()[0];
        
	}

	public boolean insert(T entity)
	{		
		try
		{
			this.em.getTransaction().begin();
			this.em.persist(entity);
			this.em.getTransaction().commit();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		} finally
		{
			if (this.em.getTransaction().isActive())
				this.em.getTransaction().rollback();
		}
	}

	public boolean update(T entity)
	{
		try
		{
			this.em.getTransaction().begin();
			this.em.merge(entity);
			this.em.getTransaction().commit();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		} finally
		{
			if (this.em.getTransaction().isActive())
				this.em.getTransaction().rollback();
		}
	}

	public boolean delete(T entity)
	{
		try
		{
			this.em.getTransaction().begin();
			this.em.remove(entity);
			this.em.getTransaction().commit();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		} finally
		{
			if (this.em.getTransaction().isActive())
				this.em.getTransaction().rollback();
		}
	}

	public boolean deleteByID(int id)
	{
		try
		{
			String deleteQuery = "delete " + this.entityClass.getSimpleName()+" where id=:id";
			this.em.getTransaction().begin();
			this.em.createQuery(deleteQuery).setParameter("id",id).executeUpdate();
			this.em.getTransaction().commit();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean deleteAll()
	{
		try
		{
			String deleteQuery = "delete " + this.entityClass.getSimpleName();
			this.em.getTransaction().begin();
			this.em.createQuery(deleteQuery).executeUpdate();
			this.em.getTransaction().commit();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}

	@SuppressWarnings("unchecked")
	public List<T> getAll()
	{
		String queryCreate = "select o from " + this.entityClass.getSimpleName() + " o";
		return this.em.createQuery(queryCreate).getResultList();
	}

	public T getByID(int id)
	{
		return this.em.find(this.entityClass, id);
	}

}
